﻿using System;
using System.Collections.Generic;

namespace FlashPay.Service.Impl
{
    using FlashPay.DAO.Interface;
    using FlashPay.Service.Interface;

    using FlashPay.EF.Models;
    using FlashPay.Entity.Response.Menu;
    using FlashPay.Entity.Request.Menu;
    using FlashPay.Entity;
    using FlashPay.Entity.Response.Permission;
    using FlashPay.Entity.Parameter;
    using System.Linq;
    using FlashPay.Entity.Enum;
    using Newtonsoft.Json;
    using FlashPay.Entity.Request;

    /// <summary>
    /// 菜单业务接口实现
    /// </summary>
    public class MenuServiceImpl:MenuService
    {
        #region 注入
        /// <summary>
        /// 用户数据接口
        /// </summary>
        private readonly MenuDao _menu;

        /// <summary>
        /// 菜单权限数据接口
        /// </summary>
        private readonly MenuPermissionDao _menuPermission;

        /// <summary>
        /// 日志权限数据接口
        /// </summary>
        private readonly LogDao _logDao;

        /// <summary>
        /// 日志模型
        /// </summary>
        private readonly LogRecord _logRecord;

        /// <summary>
        /// 注入
        /// </summary>
        /// <param name="menu">菜单数据接口</param>
        /// <param name="menuPermission">菜单数据接口</param>
        public MenuServiceImpl(MenuDao menu, MenuPermissionDao menuPermission, LogDao logDao, LogRecord logRecord)
        {
            _menu = menu;
            _menuPermission = menuPermission;
            _logDao = logDao;
            _logRecord = logRecord;
        }
        #endregion

        /// <summary>
        /// 根据编号获取菜单
        /// </summary>
        /// <param name="id">编号</param>
        /// <returns>Company</returns>
        public Menu Get(int id)
        {
            return _menu.Get(id);
        }

        /// <summary>
        /// 更新状态
        /// </summary>
        /// <param name="id">系统编号</param>
        /// <param name="status">状态</param>
        /// <returns></returns>
        public bool UpdateStatus(int id, sbyte status)
        {
            return _menu.UpdateStatus(id,status);
        }

        /// <summary>
        /// 获取节点列表
        /// </summary>
        /// <param name="id">菜单编号</param>
        /// <returns></returns>
        public JResult<List<ZtreeNodesResponse>> GetZtreeNodes(int mType,int? id)
        {
            var response = new JResult<List<ZtreeNodesResponse>>() {
                Success = false
            };

            var ztreeNodesResponse = new List<ZtreeNodesResponse>();

            //获取菜单列表
            var menuList = _menu.GetList(new MenuQueryRequest() {
                MType = mType
            });
            if (menuList != null) {
                menuList.ForEach(item => {
                    var node = new ZtreeNodesResponse()
                    {
                        id = item.Mid,
                        name = item.MName,
                        pId = (int)item.MParent,
                    };

                    if (!id.HasValue)
                    {
                        ztreeNodesResponse.Add(node);
                    }
                    else if (item.MParent.Equals(id.Value))
                    {
                        ztreeNodesResponse.Add(node);
                    }
                });

                response.Data = ztreeNodesResponse;
                response.Success = true;
            }
            
            return response;
        }

        /// <summary>
        /// 获取子节点列表
        /// </summary>
        /// <param name="parentSysNo">编号</param>
        /// <returns></returns>
        public List<ZtreeNodesResponse> GetZtreeChildNodes(int mType, int? parentSysNo)
        {
            var ztreeNodesResponse = new List<ZtreeNodesResponse>();

            //获取菜单列表
            var menuQuery = new MenuQueryRequest()
            {
                MType = mType
            };
            if (parentSysNo.HasValue) {
                menuQuery.MParent = parentSysNo.Value;
            }
            var menuList = _menu.GetList(menuQuery);
            if (menuList != null)
            {
                menuList.ForEach(item => {
                    var node = new ZtreeNodesResponse()
                    {
                        id = item.Mid,
                        name = item.MName,
                        pId = (int)item.MParent,
                    };

                    ztreeNodesResponse.Add(node);
                });
            }
            return ztreeNodesResponse;
        }

        /// <summary>
        /// 获取节点
        /// </summary>
        /// <param name="id">菜单编号</param>
        /// <returns></returns>
        public JResult<MenuResponse> GetMenuNode(int id)
        {
            var response = new JResult<MenuResponse>() {
                Success = false
            };

            var menu = _menu.Get(id);
            if (menu != null)
            {
                var menuResponse = new MenuResponse() {
                    Mid = menu.Mid,
                    MParent = menu.MParent,
                    MName = menu.MName,
                    MUrl = menu.MUrl,
                    NodeType = menu.NodeType,
                    SortNo = menu.SortNo,
                    MType = menu.MType,
                    Hide = menu.Hide,
                };

                //菜单关联的功能权限
                var permissionList = _menuPermission.GetByMenuSysNo(menuResponse.Mid);
                if (permissionList != null) {

                    var permissionResponse = new List<PermissionResponse>();

                    permissionList.ForEach(item => {
                        permissionResponse.Add(new PermissionResponse() {
                            Pid = item.Pid,
                            PParent = item.PParent,
                            PName = item.PName,
                            PCode = item.PCode,
                            NodeType = item.NodeType,
                            SortNo = item.SortNo,
                            Hide = item.Hide
                        });
                    });

                    menuResponse.PermissionResponse = permissionResponse;
                }
                response.Success = true;
                response.Data = menuResponse;
            }

            return response;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <returns></returns>
        public JResult Delete(DeleteRequest request)
        {
            var response = new JResult()
            {
                Success = false,
            };

            try
            {
                var menu = _menu.Get(request.Id);
                if (menu != null) {
                    var menuPermissionStatus = _menuPermission.DeleteByMenuSysNo(menu.Mid);
                    if (menuPermissionStatus)
                    {
                        var menuStatus = _menu.Delete(menu.Mid);
                        if (menuStatus)
                        {
                            //_logRecord.LogType = LogRecordLogType.Menu_Delete.GetHashCode();
                            //_logRecord.LogLevel = (sbyte)LogLevel.Success.GetHashCode();
                            //_logRecord.CreateDate = DateTime.Now;
                            //_logRecord.LogRemark = string.Format("菜单删除成功,菜单编号：{0}", id);
                            //_logDao.Insert(_logRecord);

                            _logRecord.LogLevel = (sbyte)LogLevel.Success.GetHashCode();
                            _logRecord.LogType = LogRecordLogType.Menu_Delete.GetHashCode();
                            _logRecord.CreateName = request.CreateName;
                            _logRecord.CreateUid = request.CreateId;
                            _logRecord.CreateDate = DateTime.Now;
                            _logRecord.LogRemark = string.Format("菜单删除成功,菜单编号：{0}", menu.Mid);
                            _logRecord.CompanyId = request.CompanyId;
                            //_logRecord.RequestData = request.RequestData;
                            _logDao.Insert(_logRecord);

                            response.Success = true;
                            response.SuccessMessage = "删除成功！";
                        }
                        else {
                            response.ErrorMessage = "删除菜单失败";
                        }
                    }
                    else {
                        response.ErrorMessage = "删除菜单关联关系失败";
                    }
                }
                
            }
            catch (Exception ex)
            {
                try
                {
                    //_logRecord.LogType = LogRecordLogType.Menu_Delete.GetHashCode();
                    //_logRecord.LogLevel = (sbyte)LogLevel.Error.GetHashCode();
                    //_logRecord.CreateDate = DateTime.Now;
                    //_logRecord.LogRemark = string.Format("菜单删除失败,菜单编号：{0}，{1}", request.Id, ex.Message);
                    //_logDao.Insert(_logRecord);

                    _logRecord.LogLevel = (sbyte)LogLevel.Error.GetHashCode();
                    _logRecord.LogType = LogRecordLogType.Menu_Delete.GetHashCode();
                    _logRecord.CreateName = request.CreateName;
                    _logRecord.CreateUid = request.CreateId;
                    _logRecord.CreateDate = DateTime.Now;
                    _logRecord.LogRemark = string.Format("菜单删除失败,菜单编号：{0}，{1}", request.Id, ex.Message);;
                    _logRecord.CompanyId = request.CompanyId;
                    //_logRecord.RequestData = request.RequestData;
                    _logDao.Insert(_logRecord);
                }
                catch { }

                response.ErrorMessage = "删除失败：" + ex.Message;
            }
            return response;
        }

        /// <summary>
        /// 菜单 保存或更新
        /// </summary>
        /// <param name="request">菜单</param>
        /// <param name="privileges">权限</param>
        /// <returns>JsonResult</returns>
        public JResult SaveMenu(MenuRequest request, List<int> privileges) {

            var response = new JResult()
            {
                Success = false
            };
            
            //模型转换
            var menu = new Menu()
            {
                Mid = (int)request.Mid,
                MParent = request.MParent,
                MName = request.MName,
                MUrl = request.MUrl,
                NodeType = (int)request.NodeType,
                SortNo = request.SortNo,
                MType = request.MType,
                Hide = request.Hide,
            };

            try
            {
                if (menu.Mid > 0)
                {
                    //数据验证(同一个父类名称不能相同)
                    var verifyName = _menu.GetList(new MenuQueryRequest()
                    {
                        NotEqualMid = menu.Mid,//不等于自己
                        MParent = menu.MParent,
                        MType = menu.MType,
                        MName = menu.MName
                    });

                    if (verifyName != null && verifyName.Any())
                    {
                        response.ErrorMessage = "同一个父类中不能有相同的名称！";
                        return response;
                    }

                    var updateStatus = _menu.Update(menu);
                    if (updateStatus)
                    {
                        _menuPermission.DeleteByMenuSysNo(menu.Mid);

                        if (privileges != null)
                        {
                            privileges.ForEach(item =>
                            {
                                if (_menuPermission.Add(new MenuPermission()
                                {
                                    MpMid = menu.Mid,
                                    MpPid = item,
                                    CreateDate = DateTime.Now
                                }) <= 0)
                                {
                                    throw new Exception("添加菜单权限失败！");
                                }
                            });
                        }

                        //日志
                        //_logRecord.LogType = LogRecordLogType.Menu_Update.GetHashCode();
                        //_logRecord.LogLevel = (sbyte)LogLevel.Success.GetHashCode();
                        //_logRecord.CreateDate = DateTime.Now;
                        //_logRecord.LogRemark = string.Format("编辑菜单成功,菜单编号：{0}", menu.Mid);
                        //_logRecord.RequestData = request.RequestData;
                        //_logDao.Insert(_logRecord);

                        _logRecord.LogLevel = (sbyte)LogLevel.Success.GetHashCode();
                        _logRecord.LogType = LogRecordLogType.Menu_Update.GetHashCode();
                        _logRecord.CreateName = request.CreateName;
                        _logRecord.CreateUid = request.CreateId;
                        _logRecord.CreateDate = DateTime.Now;
                        _logRecord.LogRemark = string.Format("编辑菜单成功,菜单编号：{0}", menu.Mid);
                        _logRecord.CompanyId = request.CompanyId;
                        _logRecord.RequestData = request.RequestData;
                        _logDao.Insert(_logRecord);
                        response.Success = true;
                    }
                    else
                    {
                        throw new Exception(string.Format("编辑菜单失败,菜单编号：{0}", menu.Mid));
                    }
                }
                else
                {
                    //数据验证
                    var verifyName = _menu.GetList(new MenuQueryRequest()
                    {
                        MParent = menu.MParent,
                        MName = menu.MName,
                        MType = menu.MType,
                    });
                    if (verifyName != null && verifyName.Any())
                    {
                        response.ErrorMessage = "同一个父类中不能有相同的名称！";
                    }

                    var menuId = _menu.Add(menu);
                    if (menuId > 0)
                    {
                        //权限处理
                        if (privileges != null)
                        {
                            privileges.ForEach(item =>
                            {
                                if (_menuPermission.Add(new MenuPermission()
                                {
                                    MpMid = menuId,
                                    MpPid = item,
                                    CreateDate = DateTime.Now
                                }) <= 0)
                                {
                                    throw new Exception("添加菜单权限失败！");
                                }
                            });
                        }

                        //日志
                        //_logRecord.LogType = LogRecordLogType.Menu_Add.GetHashCode();
                        //_logRecord.LogLevel = (sbyte)LogLevel.Success.GetHashCode();
                        //_logRecord.CreateDate = DateTime.Now;
                        //_logRecord.LogRemark = string.Format("新增菜单成功,菜单编号：{0}", menuId);
                        //_logRecord.RequestData = request.RequestData;
                        //_logDao.Insert(_logRecord);

                        _logRecord.LogLevel = (sbyte)LogLevel.Success.GetHashCode();
                        _logRecord.LogType = LogRecordLogType.Menu_Add.GetHashCode();
                        _logRecord.CreateName = request.CreateName;
                        _logRecord.CreateUid = request.CreateId;
                        _logRecord.CreateDate = DateTime.Now;
                        _logRecord.LogRemark = string.Format("新增菜单成功,菜单编号：{0}", menuId);
                        _logRecord.CompanyId = request.CompanyId;
                        _logRecord.RequestData = request.RequestData;
                        _logDao.Insert(_logRecord);
                        response.Success = true;
                    }
                    else
                    {
                        throw new Exception(string.Format("新增菜单失败,菜单名称：{0}", menu.MName));
                    }
                }
            }
            catch (Exception ex)
            {
                try
                {
                    //日志
                    //_logRecord.LogType = menu.Mid > 0 ? LogRecordLogType.Menu_Update.GetHashCode() : LogRecordLogType.Menu_Add.GetHashCode();
                    //_logRecord.LogLevel = (sbyte)LogLevel.Error.GetHashCode();
                    //_logRecord.CreateDate = DateTime.Now;
                    //_logRecord.LogRemark = string.Format("{0}菜单失败：{1}", menu.Mid > 0 ? "编辑" : "新增", ex.Message);
                    //_logRecord.RequestData = request.RequestData;
                    //_logDao.Insert(_logRecord);

                    _logRecord.LogLevel = (sbyte)LogLevel.Error.GetHashCode();
                    _logRecord.LogType = menu.Mid > 0 ? LogRecordLogType.Menu_Update.GetHashCode() : LogRecordLogType.Menu_Add.GetHashCode();
                    _logRecord.CreateName = request.CreateName;
                    _logRecord.CreateUid = request.CreateId;
                    _logRecord.CreateDate = DateTime.Now;
                    _logRecord.LogRemark = string.Format("{0}菜单失败：{1}", menu.Mid > 0 ? "编辑" : "新增", ex.Message);
                    _logRecord.CompanyId = request.CompanyId;
                    _logRecord.RequestData = request.RequestData;
                    _logDao.Insert(_logRecord);
                    response.ErrorMessage = ex.Message;
                }
                catch {
                    response.ErrorMessage = ex.Message;
                }
            }

            return response;
        }


        /// <summary>
        /// 获取菜单列表
        /// </summary>
        /// <param name="ids">系统编号列表</param>
        /// <returns>菜单列表</returns>
        public List<Menu> GetListByIds(List<int> ids)
        {
            return _menu.GetListByIds(ids);
        }

        /// <summary>
        /// 根据条件获取菜单列表
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <returns>List<Menu></returns>
        public List<MenuResponse> GetList(MenuQueryRequest request)
        {
            var menuList = _menu.GetList(request);

            var response = new List<MenuResponse>();

            #region 对象转换
            menuList.ForEach(item => {
                response.Add(new MenuResponse() {
                    Mid = item.Mid,
                    MParent = item.MParent,
                    MName = item.MName,
                    NodeType = item.NodeType,
                    MType = item.MType,
                    Hide = item.Hide,
                });
            });
            #endregion

            return response;
        }

        /// <summary>
        /// 菜单功能权限分页列表
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <returns></returns>
        public PagedList<Permission> GetMenuPermissionPager(MenuPermissionQuery query) {
            return _menuPermission.GetMenuPermissionPager(query);
        }
    }
}
